﻿using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Dpx.Models;
using Dpx.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Xamarin.Forms;
using Xamarin.Forms.Extended;

namespace Dpx.ViewModels {
    /// <summary>
    /// 搜索结果页ViewModel
    /// </summary>
    public class ResultPageViewModel : ViewModelBase {
        // *********** 绑定属性

        /// <summary>
        /// 诗词集合
        /// </summary>
        public InfiniteScrollCollection<Poetry> PoetryCollection { get; }

        /// <summary>
        /// 查询语句。
        /// </summary>
        private Expression<Func<Poetry, bool>> _where;

        /// <summary>
        /// 查询语句
        /// </summary>
        public Expression<Func<Poetry, bool>> Where {
            get => _where;
            set {
                Set(nameof(Where), ref _where, value);
                _isNewQuery = true;
            }
        }

        /// <summary>
        /// 加载状态。
        /// </summary>
        private string _status;

        /// <summary>
        /// 加载状态。
        /// </summary>
        public string Status {
            get => _status;
            set => Set(nameof(Status), ref _status, value);
        }


        /// <summary>
        /// 内容导航服务。
        /// </summary>
        private IContentNavigationService _contentNavigationService;

        // *********** 构造函数

        /// <summary>
        /// 搜索结果页ViewModel。
        /// </summary>
        /// <param name="poetryStorage">诗词存储。</param>
        /// <param name="contentNavigationService">内容存储。</param>
        public ResultPageViewModel(IPoetryStorage poetryStorage, IContentNavigationService contentNavigationService) {
            _contentNavigationService = contentNavigationService;
            PoetryCollection = new InfiniteScrollCollection<Poetry> {OnCanLoadMore = () => _canLoadMore};
            PoetryCollection.OnLoadMore = async () => {
                Status = LOADING;
                var poetries = await poetryStorage.GetPoetriesAsync(Where,
                    PoetryCollection.Count, PAGESIZE);

                if (poetries.Count < PAGESIZE) {
                    _canLoadMore = false;
                    Status = NOMORERESULT;
                }
                else {
                    Status = "";
                }

                if (PoetryCollection.Count == 0 && poetries.Count == 0) {
                    Status = NORESULT;
                }

                return poetries;
            };
        }

        // ******** 公开变量

        /// <summary>
        /// 一页显示的诗词数量。
        /// </summary>
        public const int PAGESIZE = 20;

        /// <summary>
        /// 正在载入。
        /// </summary>
        public const string LOADING = "正在载入";

        /// <summary>
        /// 没有满足条件的结果。
        /// </summary>
        public const string NORESULT = "没有满足条件的结果";

        /// <summary>
        /// 没有更多结果。
        /// </summary>
        public const string NOMORERESULT = "没有更多结果";

        // *********** 绑定命令

        /// <summary>
        /// 当页面加载完毕后执行命令。
        /// </summary>
        private RelayCommand _pageAppearingCommand;

        /// <summary>
        /// 当页面加载完毕后执行命令。
        /// </summary>
        public RelayCommand PageAppearingCommand =>
            _pageAppearingCommand ??= new RelayCommand(
                async () => await PageAppearingCommandFunction());

        public async Task PageAppearingCommandFunction() {

            if (!_isNewQuery) return;
            PoetryCollection.Clear();
            _canLoadMore = true;
            await PoetryCollection.LoadMoreAsync();
            _isNewQuery = false;
        }

        /// <summary>
        /// 诗词已点击命令
        /// </summary>
        private RelayCommand<Poetry> _poetryTappedCommand;

        /// <summary>
        /// 诗词已点击命令
        /// </summary>
        public RelayCommand<Poetry> PoetryTappedCommand => _poetryTappedCommand ??= new RelayCommand<Poetry>(
            async (p) => { await PoetryTappedCommandFunction(p); });

        public async Task PoetryTappedCommandFunction(Poetry p) =>
            await _contentNavigationService.NavigateToAsync(ContentNavigationConstant.DetailPage, p);

        /// <summary>
        /// 能够加载更多结果
        /// </summary>
        public bool _canLoadMore;

        /// <summary>
        /// 标志当前查询是否是新查询
        /// </summary>
        public bool _isNewQuery;
    }
}